package thread;
/**
 * 同步块
 * 语法:
 * synchronized(同步监视器对象){
 * 	需要多线程同步运行的代码片段
 * }
 * 
 * 同步块可以更准确的锁定需要同步运行的代码片段，有效的缩小同步范围可以在保证并发
 * 安全的前提下提高并发效率。
 * @author 范传奇
 *
 */
public class SyncDemo2 {
	public static void main(String[] args) {
		Shop shop1 = new Shop();
		Shop shop2 = new Shop();
//		Shop shop = new Shop();
		Thread t1 = new Thread() {
			public void run() {
				shop1.buy();//两个线程不存在"抢"的现象，没有并发安全问题
//				shop.buy();
			}
		};
		Thread t2 = new Thread() {
			public void run() {
				shop2.buy();
//				shop.buy();
			}
		};
		t1.start();
		t2.start();
	}
}

class Shop{
//	public void buy() {//没有任何同步约束时性能最好，但是存在并发安全问题
	/*
	 * 在方法上使用synchronized，那么指定的同步监视器对象就是this
	 */
	public synchronized void buy() {//解决了并发安全问题，但是性能不好。
//	public void buy() {
		try {
			Thread t = Thread.currentThread();
			System.out.println(t.getName()+":正在挑衣服...");
			Thread.sleep(5000);
			/*
			 * 同步块使用时要求必须指定同步监视器对象:()中的内容
			 * 该对象可以是java中任何类型的实例，只需要保证一点:多个需要同步执行
			 * 的线程看到的这个对象必须是同一个!
			 */
//			synchronized (new Object()) {//没有同步效果的！
//			synchronized (this) {
				System.out.println(t.getName()+":正在试衣服...");
				Thread.sleep(5000);
//			}
			
			
			System.out.println(t.getName()+":结账离开!");
		} catch (Exception e) {
		}
	}
}








